﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Controls;

namespace InvoicingScreen.Controls.Components
{
    //This calls simulates a large textbox with underlining by exploiting a listbox and access modifiers. Needs work and must be carefully used!
    public partial class CommentBoxCtrl : UserControl
    {
        //Create a collection to hold all the substrings
         ObservableCollection<TestString> buffer = new ObservableCollection<TestString>();

        //this constant represents how many characters long each substring will be. textBox.MaxLength MUST MATCH IN THE XAML!
        const int lineSize = 90;

        /// <summary>
        /// This string is actually an interface to the underlying string array the listbox displays in textboxes, get and set it to change the
        /// text of the control.
        ///
        ///'Comment' can bug if set to a .resx value in the XAML, avoid this if possible.
        /// </summary>
        public string Comment
        {
            //when getting this string, concatenate every string in the listbox itemsource collection into one super string and REMOVE newline characters.
            get
            {
                StringBuilder buffer = new StringBuilder();

                foreach (TestString tB in listBox.ItemsSource)
                {
                    buffer.Append(tB.testcontent.Split((new string[] { Environment.NewLine }), StringSplitOptions.None)[0]);
                }

                return buffer.ToString();
            }

            //when setting this string, take in a string value and break it into x amount of substrings based on a literal maximum string length, 
            //then bind this to a listbox for easy viewing.
            set
            {
                //Create a collection to hold all the substrings
                 buffer = new ObservableCollection<TestString>();

                //Create a stringbuilder to insert line breaks into value string.
                StringBuilder stringBuilder = new StringBuilder(value);
             
                //Set a value to record how many substrings we will need to have based on linesize and the length of the value string.
                int loopCount = (int)(stringBuilder.Length / lineSize) + 1;

                //insert newline characters into the stringbuilder every X characters Y amount of times. X = lineSize. Y = loopcount.
                for (int i = lineSize; i < loopCount * lineSize; i += lineSize)
                {
                    stringBuilder.Insert(i, Environment.NewLine);
                }

                //Create a temp substring array by splitting the stringbuilder at every newline string.
                string[] tempArray = stringBuilder.ToString().Split((new string[] {Environment.NewLine}), StringSplitOptions.None);

                //Stick each element in the substring array into the collection.
                foreach (string s in tempArray.AsEnumerable())
                {
                    //Create a new data item for storage
                    TestString testString = new TestString();

                    //assign the value of the current string in tempArray to the content of the data item
                    testString.testcontent = s;

                    //hijack the property changed event for our own nefarious purposes!
                    testString.PropertyChanged += new PropertyChangedEventHandler(TestStringPropertyChanged);

                    //add the item to the observable collection we use to set the listBox itemsource.
                    buffer.Add(testString);
                }

                //Set the listbox's itemsource to be this collection, binding the data.
                listBox.ItemsSource = buffer;
            }
        }

        //When any property is changed in a TestString in the listbox, reload the listbox - this makes text 'move up' like a real textbox.
        void TestStringPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //Store a copy of comment's underlying data with all the newline characters removed by concatenating it into a string.
            string x = Comment;

            //update the control with this copy
            Comment = x;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        public CommentBoxCtrl()
        {
            InitializeComponent();

            //Default the comment value to a static resource if no value is entered.
            Comment = InvoicingScreen.ApplicationStrings.testText;
        }       
    }
}
